<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>流程设计</title>
    <head>
        <link rel="stylesheet" href="./component/pear/css/pear.css"/>
        <link rel="stylesheet" href="./admin/css/reset.css"/>
        <!--LogicFlow core包css-->
        <link rel="stylesheet" href="./component/logicflow/core/dist/style/index.css"/>
        <!--LogicFlow extension包css-->
        <link rel="stylesheet" href="./component/logicflow/extension/lib/style/index.css"/>
    </head>
</head>
<style>
    * {
        padding: 0;
        margin: 0;
    }

    html,
    body {
        overflow: hidden;
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
    }

    .lf-control-see {
        background-image: url('');
    }

    .lf-control-import {
        background-image: url('');
    }

    .lf-control-clear {
        background-image: url('');
    }

    .lf-control-save {
        background-image: url('');
    }

    .lf-control-refresh {
        background-image: url("");
    }

    .lf-control-exit {
        background-image: url('');
    }


    .custom-minimap {
        background-image: url();
    }

    #lf-graph {
        margin: 20px 20px 0px 20px;
        width: 98%;
        height: 100%;
    }


    /*tab title*/
    .drawer-section-list ul li {
        display: inline-block;
        zoom: 1;
        vertical-align: top;
        margin-right: 20px;
        font-size: 16px;
        line-height: 34px;
        color: #373d40;
        cursor: pointer;
    }

    /*选中下划线*/
    .drawer-section-list ul .on {
        color: #488bff;
        border-bottom: 1px solid #488bff;
    }

    /*列表*/
    .drawer-section-info div {
        text-align: left;
        border-top: 1px solid #ececec;
    }
</style>

<body>

<!--画板-->
<div id="lf-graph"></div>


<!--layui依赖-->
<script src="./component/layui/layui.js"></script>
<script src="./component/pear/pear.js"></script>

<script type="text/javascript" src="./component/logicflow/core/dist/logic-flow.js"></script>
<!--LogicFlow的插件引入-->
<script type="text/javascript" src="./component/logicflow/extension/lib/Menu.js"></script>
<script type="text/javascript" src="./component/logicflow/extension/lib/DndPanel.js"></script>
<script type="text/javascript" src="./component/logicflow/extension/lib/Control.js"></script>
<script type="text/javascript" src="./component/logicflow/extension/lib/MiniMap.js"></script>
<script type="text/javascript" src="./component/logicflow/extension/lib/Group.js"></script>
<!--LogicFlow定制模型引入-->
<script type="text/javascript" src="./component/logicflow/customized/start.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/task.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/fork.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/join.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/subProcess.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/wfSubProcess.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/end.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/custom.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/decision.js"></script>
<script type="text/javascript" src="./component/logicflow/customized/transition.js"></script>

<script>

    //相关常量
    const PRIMARY_KEY = "id";
    //属性面板路径
    const URL_MAP = {
        start: './panel/start.html',
        decision: './panel/decision.html',
        task: './panel/task.html',
        custom: './panel/custom.html',
        process: './panel/process.html',
        fork: './panel/fork.html',
        join: './panel/join.html',
        subProcess: './panel/subProcess.html',
        wfSubProcess: './panel/wfSubProcess.html',
        end: './panel/end.html',
        transition: './panel/transition.html'
    };

    let $ = layui.jquery;
    let graphData = {};
    let viewer = false;
    let highLight = [];
    let commitPath = null;
    let defaultConfig = {};
    let extendAttrConfig = {};
    //接受父级的传参
    window.addEventListener('message', function (event) {
        let data = event.data;
        graphData = data.graphData !== undefined ? data.graphData : {};
        viewer = data.viewer !== undefined ? data.viewer : false;
        highLight = data.highLight !== undefined ? data.highLight : [];
        commitPath = data.commitPath !== undefined && data.commitPath !== null && data.commitPath !== '' ? data.commitPath : null;
        defaultConfig = data.config !== undefined ? data.config : {grid: true};
        extendAttrConfig = data.extendAttrConfig !== undefined ? data.extendAttrConfig : {};
        init();
        //高亮渲染
        setHighLight(highLight);
    });


    function init() {
        // 画布配置
        if (viewer) {
            defaultConfig.isSilentMode = true
        }
        const lf = new LogicFlow({
            container: document.querySelector("#lf-graph"),
            grid: {
                size: 20,
                visible: true,
                type: 'dot',
                config: {
                    color: '#ababab',
                    thickness: 1,
                },
            },
            edgeType: 'ingenious:transition',//1.2+需要默认线类型
            plugins: [Menu, DndPanel, Control, MiniMap, Group],
            keyboard: {
                enabled: true,//是否启用快捷键
                shortcuts: [
                    {
                        keys: ["del"],
                        callback: () => {
                            if (!lf) return;
                            const elements = lf.getSelectElements(true);
                            lf.clearSelectElements();
                            elements.edges.forEach((edge) => lf.deleteEdge(edge.id));
                            elements.nodes.forEach((node) => lf.deleteNode(node.id));
                        }
                    }
                ]
            }
        });
        this.lf = lf;
        this.lf.register(Task)
        this.lf.register(Custom)
        this.lf.register(Start)
        this.lf.register(End)
        this.lf.register(Decision)
        this.lf.register(Join)
        this.lf.register(Fork)
        this.lf.register(Transition)
        this.lf.register(WfSubProcess)


        //初始化操作栏
        initOp(this.lf)
        //初始化事件
        initEvent(this.lf)
        //初始化渲染一次
        this.lf.render(graphData)
    }


    function initOp(lf) {
        if (viewer) {
            // 预览模式时
            lf.extension.menu.setMenuConfig({
                nodeMenu: [],
                edgeMenu: []
            })
            return
        }
        //设置拖拽面板
        lf.extension.dndPanel.setPatternItems([
            {
                type: 'ingenious:start',
                text: '开始',
                label: '开始节点',
                properties: {},
                icon: ''
            },
            {
                type: 'ingenious:task',
                text: '用户',
                label: '用户任务',
                properties: {
                    assignee: "",
                    back_permission: "1",
                    perform_type: "ANY",
                    scope: "1",
                    task_type: "Major",
                    field: {}
                },
                icon: '',
                className: 'important-node'
            },
            {
                type: 'ingenious:custom',
                text: '自定义任务',
                label: '自定义任务',
                properties: {},
                icon: '',
                className: 'import_icon'
            },
            {
                type: 'ingenious:decision',
                label: '条件判断',
                properties: {},
                icon: ''
            },
            {
                type: 'ingenious:fork',
                label: '分支',
                properties: {},
                icon: ''
            },
            {
                type: 'ingenious:join',
                label: '合并',
                properties: {},
                icon: ''
            },
            {
                type: 'ingenious:end',
                text: '结束节点',
                label: '结束节点',
                properties: {},
                icon: ''
            },
            {
                type: 'ingenious:wfSubProcess',
                text: '子流程',
                label: '子流程',
                properties: {},
                icon: '',
                className: 'import_icon'
            },
            // {
            //     type: 'ingenious:subProcess',
            //     text: '',
            //     label: '子流程',
            //     properties: {},
            //     icon: '',
            //     className: 'import_icon'
            // }
        ])
        //设置右键菜单
        lf.extension.menu.setMenuConfig({
            nodeMenu: [
                {
                    text: "删除",
                    callback(node) {
                        lf.deleteNode(node.id);
                    },
                },
                {
                    text: "编辑文本",
                    callback: (node) => {
                        lf.editText(node.id);
                    }
                },
                {
                    text: "属性",
                    callback(node) {
                        let e = {};
                        e.data = node;
                        propertiesPanel(e)

                    }
                }
            ],
            edgeMenu: [
                {
                    text: "删除",
                    callback(edge) {
                        lf.deleteEdge(edge.id);
                    },
                },
                {
                    text: "编辑文本",
                    callback: (edge) => {
                        lf.editText(edge.id);
                    }
                },
                {
                    text: "属性",
                    callback(edge) {
                        let e = {};
                        e.data = edge;
                        propertiesPanel(e)
                    }
                }
            ],
            graphMenu: [], // 重新右键菜单空跟false 一样
        });
        //控制面板
        lf.extension.control.addItem({
            iconClass: 'lf-control-clear',
            title: 'clear',
            text: '清空',
            onClick: () => {
                lf.clearData()
            }
        })

        /**
         * 控制面板-添加查看按钮
         */
        lf.extension.control.addItem({
            iconClass: 'lf-control-see',
            title: '',
            text: '查看',
            onClick: () => {
                layui.use(['layer'], function () {
                    let layer = layui.layer;
                    layer.open({
                        type: 2,
                        area: ['800px', '500px'],
                        title: '查看流程数据',
                        maxmin: true,
                        shade: 0.1,
                        shadeClose: true,
                        content: 'panel/detail.html',
                        success: function (layero, index) {
                            // 将数据传递给子页面
                            let iframeWin = window[layero.find('iframe')[0]['name']];
                            iframeWin.child(getGraphData());
                        }, end: function (layero, index) {

                        }
                    });
                })
            }
        })

        /**
         *   控制面板-添加导入按钮
         */
        lf.extension.control.addItem({
            iconClass: 'lf-control-import',
            title: '',
            text: '导入',
            onClick: () => {
                layui.use(['layer'], function () {
                    let layer = layui.layer;
                    layer.open({
                        type: 2,
                        area: ['800px', '500px'],
                        maxmin: true,
                        title: '导入流程数据(json)',
                        shade: 0.1,
                        shadeClose: true,
                        anim: 0,
                        content: 'panel/import.html',
                        success: function (layero, index) {
                        }, end: function (layero, index) {
                        }
                    });
                })
            }
        })

        /**
         *   控制面板-刷新
         */
        lf.extension.control.addItem({
            iconClass: 'lf-control-refresh',
            title: '',
            text: '刷新',
            onClick: () => {
                location.replace(location.href)
            }
        })

        /**
         *  控制面板-保存
         */
        lf.extension.control.addItem({
            iconClass: 'lf-control-save',
            title: '',
            text: '保存',
            onClick: () => {
                saveGraphData()
            }
        })

        /**
         *   退出设计
         */
        // lf.extension.control.addItem({
        //     iconClass: "lf-control-exit",
        //     title: "",
        //     text: "退出",
        //     onClick: (lf, ev) => {
        //         layer.confirm('确认要退出吗？', function (index) {
        //             //弹出层
        //             // var index = parent.layer.getFrameIndex(window.name);
        //             // parent.layer.close(index);
        //             //关闭当前TAB
        //             parent.layui.admin.closeCurrentTab()
        //         })
        //     }
        // });

        /**
         *  小地图
         */
        lf.extension.control.addItem({
            iconClass: "custom-minimap",
            title: "",
            text: "导航",
            onClick: (lf, ev) => {
                const position = lf.getPointByClient(ev.x, ev.y);
                lf.extension.miniMap.show(
                    position.domOverlayPosition.x - 125,
                    position.domOverlayPosition.y + 40
                );
            }
        });
    }

    function initEvent(lf) {
        if (viewer) {
            return;
        }
        // 空白区右键事件-弹出流程属性表单
        const eventCenter = lf.graphModel.eventCenter
        eventCenter.on('blank:contextmenu', (args) => {
            let data = {
                name: ('name' in graphData) ? graphData.name : '',
                display_name: ('display_name' in graphData) ? graphData.display_name : '',
                expire_time: ('expire_time' in graphData) ? graphData.expire_time : '',
                instance_url: ('instance_url' in graphData) ? graphData.instance_url : '',
                instance_no_class: ('instance_no_class' in graphData) ? graphData.instance_no_class : '',
                type: 'ingenious:process'
            }
            let param = [];
            param['data'] = data;
            layer.open({
                type: 2,
                offset: 'r',
                area: ['500px', '100%'],
                title: false,
                shade: 0.1,
                closeBtn: 0,
                shadeClose: true,
                anim: -1,
                skin: 'layer-anim-right',
                move: false,
                content: URL_MAP['process'],
                success: function (layero, index) {
                    let iframe = window['layui-layer-iframe' + index]; // 找到iframe层
                    iframe.window.child(param);
                },
                end: function () {
                }
            });
        })
        //节点事件
        lf.on('node:click', (data) => {
            propertiesPanel(data)
        })
        //边线事件
        lf.on('edge:click', (data) => {
            console.log(data)


            layui.use(['layer'], function () {
                let layer = layui.layer;
                let settingType = extractValueAfterDelimiter(data.data.type, ':');
                layer.open({
                    type: 2,
                    offset: 'r',
                    area: ['500px', '100%'],
                    title: false,
                    shade: 0.1,
                    closeBtn: 0,
                    shadeClose: true,
                    anim: -1,
                    skin: 'layer-anim-right',
                    move: false,
                    content: URL_MAP[settingType],
                    success: function (layero, index) {
                        // 将数据传递给子页面
                        let iframe = window['layui-layer-iframe' + index]; // 找到iframe层
                        iframe.window.child(data);
                    }, end: function (layero, index) {

                    }
                });
            })
        })
    }


    function propertiesPanel(data) {
        let settingType = extractValueAfterDelimiter(data.data.type, ':');
        layer.open({
            type: 2,
            offset: 'r',
            area: ['500px', '100%'],
            title: false,
            shade: 0.1,
            closeBtn: 0,
            shadeClose: true,
            anim: -1,
            skin: 'layer-anim-right',
            move: false,
            content: URL_MAP[settingType],
            success: function (layero, index) {
                let iframe = window['layui-layer-iframe' + index]; // 找到iframe层
                iframe.window.child(data, extendAttrConfig);
            },
            end: function () {
            }
        });
    }

    /**
     * 对传入类型进行截取
     * @param string
     * @param delimiter
     * @returns {*}
     */
    function extractValueAfterDelimiter(string, delimiter) {
        // 找到冒号在字符串中的位置
        let delimiterIndex = string.indexOf(delimiter);
        // 如果冒号存在于字符串中，则截取冒号后面的值
        if (delimiterIndex !== -1) {
            let value = string.slice(delimiterIndex + delimiter.length);
            return value;
        } else {
            return string;
        }
    }

    /**
     * 处理表单数据
     * @param e
     * @returns {boolean}
     */
    function handlePropertyChange(e) {
        try {
            let type = extractValueAfterDelimiter(e.type, ':');
            if (type === 'process') {
                $.each(e, function (index, item) {
                    graphData[index] = item
                })
            } else if (type === 'subProcess') {
                $.each(e, function (index, item) {
                    if (in_array(index, ['id', 'x', 'y', 'text'])) {
                        return true;
                    }
                    lf.setProperties(e.id, {
                        [index]: item
                    })
                });
            } else if (in_array(type, ['start', 'fork', 'join', 'end', 'task', 'decision', 'custom', 'wfSubProcess'])) {
                if (null != e.display_name) {
                    lf.updateText(e.id, e.display_name)
                }
                //写入扩展属性
                $.each(e, function (index, item) {
                    if (in_array(index, ['id', 'display_name', 'type', 'x', 'y', 'text'])) {
                        return true;
                    }
                    lf.setProperties(e.id, {
                        [index]: item
                    })
                });
                //重新渲染
                lf.render(getGraphData())
            } else if (type === 'transition') {
                if (null != e.display_name) {
                    lf.updateText(e.id, e.display_name)
                }
                //写入扩展属性
                $.each(e, function (index, item) {
                    if (in_array(index, ['id', 'display_name', 'type', 'x', 'y', 'text'])) {
                        return true;
                    }
                    lf.setProperties(e.id, {
                        [index]: item
                    })
                });
            }
            return true;
        } catch (e) {
            return false;
        }
    }


    function setHighLight(data) {
        if (!this.lf || !data) return
        // 设置历史节点
        if (data && data['history_node_names'] !== undefined && Array.isArray(data['history_node_names'])) {
            data['history_node_names'].forEach(nodeName => {
                this.lf.setProperties(nodeName, {state: 'history'})
            })
        }
        // 设置当前节点
        if (data && data['active_node_names'] !== undefined && Array.isArray(data['active_node_names'])) {
            data['active_node_names'].forEach(nodeName => {
                this.lf.setProperties(nodeName, {state: 'active'})
            })
        }
        // 设置历史边
        if (data && data['history_edge_names'] && Array.isArray(data['history_edge_names'])) {
            data['history_edge_names'].forEach(edgeName => {
                const edgeModel = this.lf.getEdgeModelById(edgeName)
                if (edgeModel) {
                    edgeModel.setProperties({state: 'history'});
                }
            })
        }
    }


    function importProcessData(data) {
        graphData = data;
        if (this.lf) {
            this.lf.render(graphData)
        }
    }

    /**
     * 保存设计
     */
    function saveGraphData() {
        console.log('保存设计')
        console.log(getGraphData())
    }

    function getGraphData() {
        return {
            name: ('name' in graphData) ? graphData.name : '',
            display_name: ('display_name' in graphData) ? graphData.display_name : '',
            expire_time: ('expire_time' in graphData) ? graphData.expire_time : '',
            instance_url: ('instance_url' in graphData) ? graphData.instance_url : '',
            instance_no_class: ('instance_no_class' in graphData) ? graphData.instance_no_class : '',
            type_id: ('type_id' in graphData) ? graphData.type_id : '',
            ...lf.getGraphData()
        }
    }

    init();

</script>

</body>

</html>
